home *** CD-ROM | disk | FTP | other *** search
- /*
- * CBLibrary - FilePerc
- * Copyright (C) 2003 Chris Bazley
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- /* Displays % hourglass and watches for ESCAPE during file operations */
-
- /* ANSI library files */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
-
- /* RISC OS library files */
- #include "kernel.h"
- #include "flex.h"
-
- /* Other headers */
- #include "Macros.h"
- #include "msgtrans.h"
- #include "hourglass.h"
- #include "timer.h"
- #include "FedCompMT.h"
- #ifndef COMP_OPS_ONLY
- #include "LoadSaveMT.h"
- #endif
- #include "AbortFop.h"
- #include "FilePerc.h"
-
- static volatile bool time_up = true;
- static bool at_exit = false;
-
- extern _kernel_oserror shared_err_block;
-
- /* ----------------------------------------------------------------------- */
- /* Function prototypes */
-
- static void ensure_timer_removed(void);
-
- /* ----------------------------------------------------------------------- */
- /* Public functions */
-
- _kernel_oserror *perc_operation(int type, const char *file_path, unsigned int file_type, flex_ptr buffer_anchor)
- {
- assert(type == FILEPERC_OP_DECOMP || type == FILEPERC_OP_COMP
- #ifndef COMP_OPS_ONLY
- || type == FILEPERC_OP_LOAD || type == FILEPERC_OP_SAVE
- #endif
- );
-
- /* enable escape key & reset escape detection */
- if(_kernel_osbyte(229, 0, 0) == _kernel_ERROR)
- return _kernel_last_oserror();
- _kernel_escape_seen();
-
- hourglass_on();
-
- if(!at_exit) {
- atexit(ensure_timer_removed);
- at_exit = true;
- }
-
- FILE **handle = NULL;
- _kernel_oserror *err = NULL;
- int esc_seen = 0;
-
- do {
- time_up = false;
- err = timer_register(&time_up, 10); /* break 10 times a second to update hourglass */
- if(err != NULL)
- time_up = true; /* could not set up timer event */
- else {
- switch(type) {
- #ifndef COMP_OPS_ONLY
- case FILEPERC_OP_LOAD:
- err = load_fileM(file_path, buffer_anchor, &time_up, &handle, FLAG_SET(file_type, 1u<<31));
- break;
-
- case FILEPERC_OP_SAVE:
- err = save_fileM(file_path, file_type, buffer_anchor, &time_up, &handle, FLAG_SET(file_type, 1u<<31));
- break;
- #endif
- case FILEPERC_OP_DECOMP:
- err = load_compressedM(file_path, buffer_anchor, &time_up, &handle);
- break;
-
- case FILEPERC_OP_COMP:
- err = save_compressedM(file_path, file_type, buffer_anchor, &time_up, &handle);
- break;
-
- }
- ensure_timer_removed(); /* in case OS_CallAfter event still pending */
-
- if(handle != NULL) {
- unsigned int perc;
- switch(type) {
- #ifndef COMP_OPS_ONLY
- case FILEPERC_OP_LOAD:
- case FILEPERC_OP_SAVE:
- perc = get_loadsave_perc(&handle);
- break;
- #endif
- case FILEPERC_OP_DECOMP:
- perc = get_decomp_perc(&handle);
- break;
-
- case FILEPERC_OP_COMP:
- perc = get_comp_perc(&handle);
- break;
-
- default:
- perc = 0;
- break;
- }
- hourglass_percentage(perc);
- }
-
- esc_seen = _kernel_escape_seen(); /* check for escape condition */
- }
- } while(handle != NULL && err == NULL && !esc_seen);
- hourglass_off();
-
- /* disable escape key & clear any escape condition */
- if(_kernel_osbyte(229, 1, 0) == _kernel_ERROR
- || _kernel_osbyte(124, 0, 0) == _kernel_ERROR) {
- if(err == NULL)
- err = _kernel_last_oserror();
- }
-
- /* If stopped in mid-operation then close it down */
- if(handle != NULL)
- abort_file_op(&handle);
-
- /* Inform the user if we stopped due to them pressing ESCAPE */
- if(esc_seen && err == NULL) {
- WRITE_ERR(shared_err_block, "Escape");
- err = &shared_err_block;
- }
-
- /* If error, then free any allocated block */
- if((type == FILEPERC_OP_LOAD || type == FILEPERC_OP_DECOMP) && err != NULL && *buffer_anchor != NULL) {
- flex_free(buffer_anchor);
- *buffer_anchor = NULL;
- }
-
- return err; /* success */
- }
-
- /* ----------------------------------------------------------------------- */
- /* Private functions */
-
- static void ensure_timer_removed(void)
- {
- /* Last-ditch effort to remove OS_CallAfter routine, if still pending */
- if(!time_up) {
- timer_deregister(&time_up);
- /* (suppress errors, as event may occur between check and removal) */
- time_up = true;
- }
- }
-